home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 11 / develop 11 code / Exceptions / DPrintf.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  7.6 KB  |  334 lines  |  [TEXT/MPS ]

  1.  
  2. /*********************************************************************
  3.  
  4. FILENAME
  5.     DPrintf.c
  6.  
  7. DESCRIPTION
  8.     This is the dprintf Macsbug dcmd for use with Exceptions.h.
  9.  
  10. COPYRIGHT
  11.     Copyright © Apple Computer, Inc. 1990-1991
  12.     All rights reserved.
  13.  
  14. ROUTINES
  15.     EXTERNALS
  16.         CommandEntry (dprintf)
  17.     INTERNALS
  18.         FormatFloat
  19.         FormatLong
  20.  
  21. MODIFICATION HISTORY
  22.     11/05/91    Sean Parent
  23.         1) Cleaned up for Develop article.
  24.     
  25. *********************************************************************/
  26.  
  27. /*********************************************************************
  28.  
  29. INCLUDES
  30.  
  31. *********************************************************************/
  32.  
  33. #include <string.h>
  34. #include <stdio.h>
  35. #include <Types.h>
  36. #include <FixMath.h>
  37. #include "dcmd.h"
  38. #include "put.h"
  39.  
  40. /*********************************************************************
  41.  
  42. PROTOTYPES
  43.  
  44. *********************************************************************/
  45.  
  46. void FormatFloat(const char* format, short numArgs, long firstArg,
  47.     long secondArg, float theFloat);
  48.  
  49. void FormatLong(const char* format, short numArgs, long firstArg,
  50.     long secondArg, long theLong);
  51.  
  52. /*********************************************************************
  53.  
  54. ROUTINE
  55.     CommandEntry
  56.  
  57. DESCRIPTION
  58.     This is the implementation of the dprintf dcmd. See Exceptions.h
  59.     for more information.
  60.  
  61. *********************************************************************/
  62.  
  63. pascal void CommandEntry(dcmdBlock* paramPtr)
  64. {
  65.     switch (paramPtr->request) {
  66.     case dcmdInit:
  67.         break;
  68.     case dcmdDoIt:
  69.         {
  70.             char        format[256];
  71.             size_t    formatSize;
  72.             short        i, j, numArgs;
  73.             long        firstArg, secondArg;
  74.             short*    shortWalker;
  75.             Fixed*    fixedWalker;
  76.             char*        nextp;
  77.             char*        convChar;
  78.             char*        stackPtr =
  79.                 (char*)paramPtr->registerFile[A7Register];
  80.             unsigned    char* formatWalker = *((char**)stackPtr)++;
  81.             
  82.             dcmdSwapWorlds(); /* not necessary */
  83.             
  84.             /* start scanning until end of format string */
  85.             
  86.             while (*formatWalker != '\0') {
  87.  
  88.                 /*
  89.                     Find the next format spec (i.e. %d) and print out
  90.                     anything before it.
  91.                 */
  92.                 
  93.                 nextp = strchr(formatWalker, '%');
  94.                 if (nextp == nil)
  95.                     nextp = formatWalker + strlen(formatWalker);
  96.  
  97.                 PutBytesTo(formatWalker, nextp - formatWalker, 0);
  98.                 formatWalker = nextp;
  99.                 
  100.                 if (*formatWalker == '\0') break;
  101.  
  102.                 /*
  103.                     Find the length of the format spec (skip initial % and
  104.                     include the convertion char)
  105.                 */
  106.                 
  107.                 formatSize = strcspn(formatWalker + 1,
  108.                     "bcdeEfFgGijJMopPrRsTuxX%") + 2;
  109.                 
  110.                 /* Make a copy of the format spec. */
  111.                 
  112.                 memcpy(format, formatWalker, formatSize);
  113.                 format[formatSize] = (char)'\0';
  114.                 
  115.                 /*
  116.                     If the spec contains "*" in place of field width or
  117.                     precision then get the width and/or precision from
  118.                     the stack.
  119.                 */
  120.                 
  121.                 i = (short)(strcspn(format, "*") + 1);
  122.                 if (i < formatSize) {
  123.                     firstArg = *((long*)stackPtr)++;
  124.                 
  125.                     j = (short)(strcspn(format + i, "*") + i + 1);
  126.                     if (j < formatSize) {
  127.                         secondArg = *((long*)stackPtr)++;
  128.                         numArgs = 2;
  129.                     } else numArgs = 1;
  130.                 } else numArgs = 0;
  131.                 
  132.                 formatWalker += formatSize; /* increment the format p */
  133.                 
  134.                 /*
  135.                     Get address of conversion character. Address is used
  136.                     so it can be changed directly in the format spec.
  137.                 */
  138.                 
  139.                 convChar = &format[formatSize - 1];
  140.                 
  141.                 /*
  142.                     If the conversion character requires special treatment
  143.                     then fix it up here. Otherwise do the standard
  144.                     formatting.
  145.                 */
  146.                 
  147.                 switch (*convChar) {
  148.                 case 'b': /* boolean */
  149.                     if (*((long*)stackPtr)++) PutCStr("true");
  150.                     else PutCStr("false");
  151.                     break;
  152.                 case 'j': /* Point */
  153.                     *convChar = 'd';
  154.                     
  155.                     for (i = 1; i >= 0; --i) {
  156.                         FormatLong(format, numArgs, firstArg, secondArg,
  157.                             *((short*)stackPtr)++);
  158.                         if (i != 0) PutCStr(", ");
  159.                     }
  160.                     break;
  161.                 case 'J': /* point* */
  162.                     *convChar = 'f';
  163.                     
  164.                     fixedWalker = *((Fixed**)stackPtr)++;
  165.                     
  166.                     for (i = 1; i >= 0; --i) {
  167.                         FormatFloat(format, numArgs, firstArg, secondArg,
  168.                             (float)*fixedWalker++ / 0x00010000);
  169.                                                     
  170.                         if (i != 0) PutCStr(", ");
  171.                     }
  172.                     break;
  173.                 case 'T': /* Fract */
  174.                     *convChar = 'f';
  175.                     
  176.                     FormatFloat(format, numArgs, firstArg, secondArg,
  177.                         (float)(*((Fract*)stackPtr)++) / 0x40000000);
  178.                                                                 
  179.                     break;
  180.                 case 'M': /* mapping */
  181.                     *convChar = 'f';
  182.                     
  183.                     fixedWalker = *((Fixed**)stackPtr)++;
  184.                     
  185.                     for (j = 2; j >= 0; --j) {
  186.                         for (i = 1; i >= 0; --i) {
  187.                             FormatFloat(format, numArgs, firstArg, secondArg,
  188.                                 (float)*fixedWalker++ / 0x00010000);
  189.                             
  190.                             PutCStr(", ");
  191.                         }
  192.                         FormatFloat(format, numArgs, firstArg, secondArg,
  193.                             (float)(*(Fract*)fixedWalker++) / 0x40000000);
  194.                         
  195.                         if (j != 0) PutCStr("\n");
  196.                     }
  197.                     break;
  198.                     
  199.                 case 'r': /* Rect* */
  200.                     *convChar = 'd';
  201.                     
  202.                     shortWalker = *((short**)stackPtr)++;
  203.                     
  204.                     for (i = 3; i >= 0; --i) {
  205.                         FormatLong(format, numArgs, firstArg, secondArg,
  206.                             *shortWalker++);
  207.                         
  208.                         if (i != 0) PutCStr(", ");
  209.                     }
  210.                     break;
  211.                 case 'R': /* rectangle* */
  212.                     *convChar = 'f';
  213.                     
  214.                     fixedWalker = *((Fixed**)stackPtr)++;
  215.                     
  216.                     for (i = 3; i >= 0; --i) {
  217.                         FormatFloat(format, numArgs, firstArg, secondArg,
  218.                             (float)*fixedWalker++ / 0x00010000);
  219.                                                     
  220.                         if (i != 0) PutCStr(", ");
  221.                     }
  222.                     break;
  223.                 case 'F': /* Fixed */
  224.                     *convChar = 'f';
  225.                     
  226.                     FormatFloat(format, numArgs, firstArg, secondArg,
  227.                         (float)(*((Fixed*)stackPtr)++) / 0x00010000);
  228.                                         
  229.                     break;
  230.                 case 'f':
  231.                 case 'e':
  232.                 case 'E':
  233.                 case 'g':
  234.                 case 'G':
  235.                     FormatFloat(format, numArgs, firstArg, secondArg,
  236.                         *((extended*)stackPtr)++);
  237.                     break;
  238.                 default:
  239.                     FormatLong(format, numArgs, firstArg, secondArg,
  240.                         *((long*)stackPtr)++);
  241.                     break;
  242.                 }
  243.             }
  244.             PutLine();
  245.             
  246.             dcmdSwapWorlds();
  247.         }
  248.         break;
  249.     case dcmdHelp:
  250.         dcmdDrawLine(
  251.         "\pdprintf");
  252.         dcmdDrawLine(
  253.         "\p   dprintf is used to display information from a C");
  254.         dcmdDrawLine(
  255.         "\p   application. See Exceptions.h for more information.");
  256.         break;
  257.     default:
  258.         dcmdDrawLine("\punknown request");
  259.         break;
  260.     }
  261. }; /* CommandEntry */
  262.  
  263. /*********************************************************************
  264.  
  265. ROUTINE
  266.     FormatFloat
  267.  
  268. DESCRIPTION
  269.     This will format a float according to the format string.
  270.  
  271. *********************************************************************/
  272.  
  273. void FormatFloat(const char* format, short numArgs, long firstArg,
  274.     long secondArg, float theFloat)
  275. {
  276.     char    final[256];
  277.  
  278.     switch (numArgs) {
  279.     case 0:
  280.         sprintf(final, format, theFloat);
  281.         break;
  282.     case 1:
  283.         sprintf(final, format, firstArg, theFloat);
  284.         break;
  285.     case 2:
  286.         sprintf(final, format, firstArg, secondArg, theFloat);
  287.         break;
  288.     }
  289.     PutCStr(final);
  290. } /* FormatFloat */
  291.  
  292. /*********************************************************************
  293.  
  294. ROUTINE
  295.     FormatFloat
  296.  
  297. DESCRIPTION
  298.     This will format a long according to the format string.
  299.  
  300. *********************************************************************/
  301.  
  302. void FormatLong(const char* format, short numArgs, long firstArg,
  303.     long secondArg, long theLong)
  304. {
  305.     char    final[256];
  306.  
  307.     switch (numArgs) {
  308.     case 0:
  309.         sprintf(final, format, theLong);
  310.         break;
  311.     case 1:
  312.         sprintf(final, format, firstArg, theLong);
  313.         break;
  314.     case 2:
  315.         sprintf(final, format, firstArg, secondArg, theLong);
  316.         break;
  317.     }
  318.     PutCStr(final);
  319. } /* FormatLong */
  320.  
  321. /*********************************************************************
  322.  
  323. STUBS
  324.  
  325. DESCRIPTION
  326.     The following are stubs to override the C library routines so that
  327.     the dcmd isn’t so big. Neither will ever be called by sprintf.
  328.  
  329. *********************************************************************/
  330.  
  331. size_t fwrite (const void *, size_t, size_t, FILE *) { return(0); }
  332. _flsbuf() {}
  333.  
  334.